package com.hbnu.service;

import com.hbnu.dao.ShareDao;
import com.hbnu.dao.UserDao;
import com.hbnu.entity.ShareStat;
import com.hbnu.entity.UserFile;
import com.hbnu.enums.Status;

import java.util.*;
import java.util.stream.Collectors;

import static com.hbnu.service.FunctionService.fileTransferService;
import static com.hbnu.service.FunctionService.userFileService;
import static com.hbnu.tools.PrintTool.*;
import static com.hbnu.tools.PrintTool.println;
import static com.hbnu.tools.ScannerTool.nextInt;
import static com.hbnu.tools.ScannerTool.nextLine;
import static com.hbnu.tools.UserFileTool.*;
import static com.hbnu.web.Client.idUserFileMap;
import static com.hbnu.web.Client.user;

public class ShareService extends AbstractFunctionService {
    private final ShareDao shareDao=new ShareDao();
    private final UserDao userDao=new UserDao();

    public ShareService(){
        cmdMap.put("sharelist",this::sharelist);

        oneMap.put("shareclose",this::shareclose);
        oneMap.put("share",this::share);
        oneMap.put("shareid",this::shareid);
        oneMap.put("code",this::code);

    }

    //打印分享表
    private void sharelist() {
        List<ShareStat> shareList = shareDao.getShareList(user.getUid());
        printShareList(shareList);
    }
    //取消链接
    private void shareclose(String id){
        try {
            if(shareDao.shareClose(Integer.parseInt(id))){
                println("已取消分享！");
            }else {
                println("取消分享失败！");
            }
        }catch (Exception e){
           throw new RuntimeException("id无效");
        }
    }
    //分享
    private void share(String path){
        //先获得pid
        share0(pathToFid(path));
    }
    //分享id
    private void shareid(String id){
        share0(idToFid(id));
    }
    //分享
    private void share0(int fid){
        //生成分享uuid 默认没有密码
        print("提取码: ");
        String pas = nextLine();
        int time=nextInt("有效时间(h): ");
        time=time==-1?24:time;
        String uuid = UUID.randomUUID().toString();
        ShareStat shareStat=new ShareStat();
        //计算文件大小
        long size = userFileService.getFSize(fid);
        //将分享内容合并成字符串
        if(idUserFileMap.get(fid).hasChildren()) {
            List<Integer> fidList = getFidList(fid);
            //单文件或文件夹
            String text = fidList.stream()
                    .map(String::valueOf) // 将 Integer 转为 String
                    .collect(Collectors.joining(","));
            shareStat.setText(text);
        }else {
            shareStat.setText(String.valueOf(fid));
        }
        shareStat.setSize(size);
        shareStat.setFid(fid);
        shareStat.setUuid(uuid);
        shareStat.setPwd(pas);

        if(shareDao.createShare(user.getUid(),shareStat,time))
            println("分享码: "+uuid);
        else
            println("数据库有问题！");
    }

    private void code(String code){
        //判断是否有效、存在
        print("提取码: ");
        String pas = nextLine();
        //分享的fid
        ShareStat shareStat =shareDao.getShareFid(code,pas);
        int fid=shareStat.getFid();
        //获得数据，显示文件树
        Map<Integer, UserFile> tmp_idUserFileMap=shareDao.getShareF(shareStat.getText());
        //从这里开始遍历 忽略空root
        UserFile userFile = tmp_idUserFileMap.get(fid);
        println("分享内容: ");
        if(userFile.is_file())
            println(userFile.getFname());
        else
            printShareTree(userFile,tmp_idUserFileMap);
        //下载或保存
        print("share: 保存或下载链接内容?(s/d): ");
        String s = nextLine();
        if (s.equalsIgnoreCase("S")) {
            //判断大小
            if(user.getSpace()-user.getSize()<shareStat.getSize()){
                println("空间不足,无法保存!");
                return;
            }

            //不允许自己保存自己
            if (user.getUid().equals(shareStat.getUid())) {
                println("不能保存本人的链接");
                return;
            }
            //保存 直接默认根目录保存位置
            //将原父id移除
            tmp_idUserFileMap.remove(userFile.getPid());
            userFile.setPid(user.getFolder_id());
            //设置一个唯一名，判断文件夹下是否存在
            userFile.setFname(getUniqueUserFileName(userFile.getPid(),userFile.getFname()));
            //新旧id对应map userFile的fid、pid已经更新
            Map<Integer,Integer> keyMap=shareDao.saveShare(user.getUid(),fid,tmp_idUserFileMap);
            if(keyMap!=null) {
                //更新临时map 只需要层级更新即可
                for (Integer key:keyMap.keySet()){
                    UserFile file = tmp_idUserFileMap.remove(key);
                    //子list更新
                    if (file.hasChildren()){
                        List<Integer> list = file.getList();
                        list.replaceAll(keyMap::get);
                    }
                    tmp_idUserFileMap.put(keyMap.get(key),file);
                }
                fid=keyMap.get(fid);
                //扣除空间
                userDao.updateAddSize(user.getUid(),shareStat.getSize());
                user.setSize(user.getSize()+shareStat.getSize());
                //内容进行缓存,将临时map加入
                idUserFileMap.get(user.getFolder_id()).addList(fid);//根目录的儿子
                idUserFileMap.putAll(tmp_idUserFileMap);
                //路径更新
                updatePathMap(fid);
                //更新本地缓存
                println("保存成功!");
            }
            else
                println("保存失败!");
        }else if(s.equalsIgnoreCase("D")) {
            //直接下载
            fileTransferService.down0(Status.def_ClientPath,fid,tmp_idUserFileMap);
        }
        //保存需要对大小检查

    }
}
